package org.example.customs.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.example.commons.common.Result;
import com.example.commons.entity.Collect;
import com.example.commons.entity.Teach;
import com.example.commons.entity.User;
import com.example.commons.entity.Video;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.example.customs.client.BaseClient;
import org.example.customs.service.CollectService;
import org.example.customs.service.TeachService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * @program: authority-v3.0.7
 * @ClassName:CollectController
 * @description: CollectController前端控制器
 * @author:dyy
 * @Version 3.0
 **/

@Tag(name = "攻略收藏 前端控制器")
@RestController
@RequestMapping("/collect")
public class CollectController {
    @Resource
    private CollectService collectService;

    @Resource
    private TeachService teachService;

    @Resource
    private BaseClient baseClient;


    /**
     * 新增
     *
     * @param collect
     * @return
     */
    @Operation(summary = "新增")
    @PostMapping
    public Result save(@RequestBody Collect collect) {
        collect.setUid(StpUtil.getLoginIdAsLong());
        if (collectService.list(new LambdaQueryWrapper<Collect>().eq(Collect::getUid,collect.getUid()).eq(Collect::getAid,collect.getAid())).size()>0){
            collectService.remove(
                    new LambdaQueryWrapper<Collect>().eq(Collect::getUid,collect.getUid()).eq(Collect::getAid,collect.getAid())
            );
            return Result.success("取消收藏成功！");
        }else{
            collect.setCreateTime(LocalDateTime.now());
            collectService.save(collect);
            return Result.success("收藏成功！");
        }
    }


    /**
     * 修改
     *
     * @param id
     * @param collect
     * @return
     */
    @Operation(summary = "修改")
    @PutMapping("/{id}")
    public Result update(@PathVariable Long id, @RequestBody Collect collect) {
        return Result.success(collectService.updateById(collect));
    }


    /**
     * 查询所有Collect
     *
     * @return
     */
    @Operation(summary = "查询所有Collect")
    @GetMapping
    public Result findAll() {
        return Result.success(collectService.list());
    }


    /**
     * 获取单个
     *
     * @param id
     * @return
     */
    @Operation(summary = "获取单个")
    @GetMapping("/{id}")
    public Result findOne(@PathVariable Integer id) {
        return Result.success(collectService.getById(id));
    }


    /**
     * 用户分页显示
     *
     * @param uid
     * @param aid
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Operation(summary = "用户分页显示")
    @GetMapping("/page")
    public Result findPage(
            @RequestParam(defaultValue = "") Long uid,
            @RequestParam(defaultValue = "") Long aid,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        LambdaQueryWrapper<Collect> queryWrapper = buildQueryWrapper(uid, aid, true);
        return Result.success(processPageResult(
                collectService.page(new Page<>(pageNum, pageSize), queryWrapper)
        ));
    }

    /**
     * 后端分页显示
     *
     * @param uid
     * @param aid
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Operation(summary = "后端分页显示")
    @GetMapping("/back/page")
    public Result findBackPage(
            @RequestParam(defaultValue = "") Long uid,
            @RequestParam(defaultValue = "") Long aid,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        LambdaQueryWrapper<Collect> queryWrapper = buildQueryWrapper(uid, aid, false);
        return Result.success(processPageResult(
                collectService.page(new Page<>(pageNum, pageSize), queryWrapper)
        ));
    }


    /**
     * 单个删除
     *
     * @param id
     * @return
     */
    @Operation(summary = "单个删除")
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        return Result.success(collectService.removeById(id));
    }


    /**
     * 根据用户id删除
     *
     * @param userId
     * @return
     */
    @Operation(summary = "根据用户ID删除所有收藏")
    @DeleteMapping("/user/{userId}")
    public Result deleteByUserId(@PathVariable Long userId) {
        LambdaQueryWrapper<Collect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Collect::getUid, userId);
        return Result.success(collectService.remove(queryWrapper));
    }


    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Operation(summary = "批量删除")
    @DeleteMapping("/batch/{ids}")
    @Transactional
    public Result deleteByIds(@PathVariable String[] ids) {
        return Result.success(collectService.removeByIds(Arrays.asList(ids)));
    }


    /**
     * 批量导出
     * 使用的技术为alibaba下面的easyexcel
     * 写数据
     *
     * @param ids
     * @return
     */
    @Operation(summary = "批量导出")
    @GetMapping("/batch/export/{ids}")
    public void exportByIds(@PathVariable String[] ids, HttpServletResponse response) throws IOException {
        List<Collect> list = collectService.listByIds(Arrays.asList(ids));

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("collect导出数据", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), Collect.class).sheet("sheel1").doWrite(list);

    }


    /**
     * 批量导入
     * 使用的技术为alibaba下面的easyexcel
     * 读数据
     *
     * @param file
     */
    @Operation(summary = "批量导入")
    @PostMapping("/batch/upload")
    public Result writeExcel(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), Collect.class, new PageReadListener<Collect>(dataList -> {
            dataList.forEach(entity -> collectService.save(entity.toBuilder().id(null).build()));
        })).sheet().doRead();
        return Result.success();
    }


    /**
     * 强制用户智能查看自己的数据
     *
     * @param uid
     * @param aid
     * @param isUserPage
     * @return
     */
    private LambdaQueryWrapper<Collect> buildQueryWrapper(Long uid, Long aid, boolean isUserPage) {
        LambdaQueryWrapper<Collect> queryWrapper = new LambdaQueryWrapper<>();

        // 确保只查询 aid 不为空的记录
        queryWrapper.isNotNull(Collect::getAid);

        // 用户分页强制绑定当前用户ID
        if (isUserPage) {
            queryWrapper.eq(Collect::getUid, StpUtil.getLoginIdAsLong());
        }

        // 动态条件过滤
        if (uid != null && uid != 0) {
            queryWrapper.eq(Collect::getUid, uid);
        }
        if (aid != null && aid != 0) {
            queryWrapper.eq(Collect::getAid, aid);
        }

        // 角色权限控制（用户角色只能查自己）
        if (StpUtil.hasRole("user")) {
            queryWrapper.eq(Collect::getUid, StpUtil.getLoginIdAsLong());
        }

        return queryWrapper.orderByDesc(Collect::getId);
    }

    private Page<Collect> processPageResult(Page<Collect> page) {
        page.getRecords().forEach(collect -> {
            // 用户信息反序列化
            User user = JSONUtil.toBean(
                    JSONUtil.toJsonStr(baseClient.getUserById(collect.getUid())),
                    User.class
            );
            collect.setUser(ObjectUtil.isNotEmpty(user) ? user : new User());

            // 教程信息查询
            Teach teach = teachService.getById(collect.getAid());
            collect.setTeach(ObjectUtil.isNotEmpty(teach) ? teach : new Teach());
        });
        return page;
    }
}